perm filename JUST[E,ALS]4 blob
sn#229819 filedate 1976-08-11 generic text, type T, neo UTF8
;JCTAB PINXLT PARGET NEXTLI
COMMENT ⊗
Register assignments used in main section of JUST (and related routines)
A Input character pointer
B Input line address
C Current character
D Output character pointer
E Address of table defining data region
F Usual flag word
G Character count for output line (-x,,0 at start)
H Special flag word
I Address of line into which characters are going
J Input char count for TJ commands
K Output tab field termination position for TJ commands
DSP Current dispatch table address
P Stack pointer, as usual
Q Several counting jobs and to index TABOLD and TABTAB
T Temporary
TT Temporary
Special flag usage with F during JUST etc. (after initial normal usage)
Right half of F
NEG set to 0 for JUST, to 1 for JFILL
REL set to 0 for no par. break, to 1 for par. break
Left half of F
TF1 used in JPREAD to keep neg sign info and then
set to 0 foe first pass, to 1 for second pass in JUST
TF2 set to 0 for JUST and JFILL, to 1 for TJUST and TFILL
TF3 set to 1 for JSTOP and JJSTOP commands
End of comment ⊗
;Special flags tested against H (for use with JUST and related commands)
JUSF←←200000 ;CR, LF, VT, FF, SP, TAB, . ! ?
; LSPC←←100000 ;Special character, previously defined
; NUMF←←40000 ;Number " "
JALL←←20000 ;Dispatch on all characters
; LETF←←10000 ;Letter (with LT2F => lower case)
; LT2F←←4000 ;Alone=> $ % . _
JTBF←←2000 ;TAB
JCRF←←1000 ;CR, LF, FF, VT
;Dispatch displacements used in following table
; 0 CR, LF, NUL and all disallowed chars. for in-core pages
; 1 TAB (11)
; 2 Space (40)
; 3 Sentence terminating punctuation . ? !
; 4 Closures ) ] > } "
; 5 All other normal characters
;Special character-dispatch table for use with JUST and related commands
JCTAB: JALL!JUSF,,(DSP) ;NUL 0
REPEAT 10<JALL,,5(DSP)> ;↓ α β ∧ ¬ ε π λ 1,2,3,4,5,6,7,10
JALL!JUSF!JTBF!LSPC,,1(DSP) ;TAB 11
REPEAT 3,<JALL!JUSF!JCRF!LSPC,,(DSP)> ;LF,VT,FF 12,13,14
JALL!JUSF!JCRF!LSPC,,(DSP) ;CR 15
JALL,,5(DSP) ;∞ 16
JALL,,5(DSP) ;∂ 17
REPEAT 20,<JALL,,5(DSP)> ; ⊂ ⊃ ∩ ∪ ∀ ∃ ⊗ ↔ _ → ~ ≠ ≤ ≥ ≡ ∨ 20 thru 37
JALL!JUSF,,2(DSP) ;SP 40
JALL!JUSF,,3(DSP) ;! 41
JALL,,4(DSP) ;" 42
REPEAT 5,<JALL,,5(DSP)> ;# % & ' 43,44,45,46,47
JALL,,5(DSP) ;( 50
JALL,,4(DSP) ;) 51
REPEAT 4,<JALL,,5(DSP)> ;* + , - 52,53,54,55
JALL!JUSF,,3(DSP) ;. 56
JALL,,5(DSP) ;/ 57
REPEAT 12,<JALL!NUMF,,5(DSP)> ;0,1,2,3,4,5,6,7,8,9 60 thru 71
REPEAT 2,<JALL,,5(DSP)> ; : ; 72,73
REPEAT 2,<JALL,,5(DSP)> ; < = 74,75
JALL,,4(DSP) ; > 76
JALL!JUSF,,3(DSP) ;? 77
JALL,,5(DSP) ;@ 100
REPEAT 32,<JALL!LETF,,5(DSP)> ;A to Z 101 thru 132
REPEAT 2,<JALL,,5(DSP)> ;[ \ 133,134
JALL,,4(DSP) ;] 135
REPEAT 3,<JALL,,5(DSP)> ;↑ ← ` 136,137,140
REPEAT 32,<JALL!LETF!LT2F,,5(DSP)> ;a th z 141 thru 172
JALL,,5(DSP) ;{ 173
JALL,,5(DSP) ;| 174
JALL!JUSF!LSPC,,(DSP) ;ALT 175
JALL,,4(DSP) ;} 176
JALL!JUSF!NSPEC,,(DSP) ;RUBOUT 177
MINTXT←←3 ;Minimum allowed text length or TAB field
TJSCNT←←2 ;Minimum number of spaces to terminate a TAB field
TABCNT←←40 ;Allow 32 tabs. NOTE: This number must not exceed
;the size of BUF2
JPT1←←0
JPT2←←1
JETST←←2
JLPTR←←3
JCPTR←←4
JEXIT←←5
JPTAB: ARRLIN
,PAGE ;STUPID FAIL
BOTSTR
LINES
CHARS
PUSHJ P,LINSET
JRST SETWRT
JATAB: ATTBUF
ATTBUF
ATTBUF
ATTNUM
ATTSIZ
MOVE T,ATTNUM
CAILE T,ATTMAX
MOVEI T,ATTMAX
PUSHJ P,EXSET
JRST ATTWRT
; Locations to hold Margin specifications
IMPURE
JSWTCH: 0 ;Switch value to index SWTAB (set for N initially)
JSWTC2: 0 ;Temporary value only
TJSWTC: 2 ;Switch value for TABLE, TJUST and TJFILL (R initially)
PMAR: 4 ;Paragraph margin indent
LMAR: 0 ;Left justifying margin indent
RMAR: =74 ;Right justifying margin.
BNUM: -1 ;Number of blank lines between paragraphs
PMARO: 4 ;Old values saved as old text indicators
LMARO: 0
RMARO: =74
BNUMO: -1
JPMAR: 0 ;Values typed in with command
JLMAR: 0
JRMAR: =74
JBNUM: -1
JPMARO: 0
JLMARO: 0
JRMARO: =74
JBNUMO: -1
GPMAR: 0 ;Values determined by JGETX
GLMAR: 0
GRMAR: =74
GBNUM: -1
TPMAR: 0
TLMAR: 0
TRMAR: =74
TBNUM: -1
TPMARO: 0
TLMARO: 0
TRMARO: =74
TBNUMO: -1
DTBCNT: 0
DSPCNT: 0
INMAR: 4
AMAR: 0
TABOLD: BLOCK TABCNT ;Old tabulations
-1 ;Guard cell
TABTAB: BLOCK TABCNT ;New tabulations
-1 ;Guard cell
RJMARS: =80 ;Sticky JOIN right margin allows room for some editing.
BREAKV: =80 ;Break value (always sticky)
;Memory locations to hold other variables
JCNT: 0 ;Count of lines to be processed
JCNTC: 0 ;Current value of JCNT during first pass
JPTR: 0 ;Location of first line of text being processed
JPTRC: 0 ;Location of first line of group currently being handled
JRPT: 0 ;Next line after text being processed
JWCOL: 0 ;Char count at last word break
JSCNT: 0 ;Word break count
JBUGR: 0 ;Bugger factor to distribute extra spaces
JWPT: 0 ;Accumulated count of extra spaces added
JSINC: 0 ;Needed spaces times 8
JSIZE: 0 ;JSINC times number of breaks already processed
JMARG: 0 ;Current output line's left margin
PARFLG: 0 ;Set for new par. conditions as defined by PMARO, LMARO and BNUMO
; Value assigned to PARFLG
; 0 means blank line needed to signal new par.
; -1 means new par. every new line
; +1 means new par if indent is >1
; X>1 means new par. if indent is =X
PURE
;J1DSP J2DSP J3DSP J4DSP J5DSP J6DSP J7DSP
; Action on reaching a CR in the input text
J2CR: TLNN F,TF1 ;Is this the first pass
JRST J2CR2 ;Yes
PUSHJ P,NEXTLI ;Finish off line and get next
SOSG JCNT
JRST J2CR5 ;We should never get here, but just in case
CAMN B,ARRLIS ;Does the data come from the original ARRLIN?
MOVEM I,ARRLIS ;Yes, so change pointer
J2CR1: MOVEI C,40 ;Replace CR with a space and cont.
SOS (P) ;To interpret the CR
POPJ P,
; First pass treatment
J2CR2: SOSLE JCNTC
JRST J2CR3
TRO F,ARG ;Set end of text signal for second pass
JRST J2CR4 ;Treat end of text as end of par. here
J2CR3: PUSHJ P,PARGET ;To get correct par info.
TRNN F,REL
JRST J2CR1 ;No new par. so replace CR with space and continue
J2CR4: TRO F,REL ;May enter here if end of data
CAIN DSP,J1DSP ;Save data only after a non-space last char.
JRST J2CR5
AOS JSCNT ;Add to word break count
HRRZM G,JWCOL ;Char count at this word break
J2CR5: AOS (P) ;Forces an exit from loop without incrementing G
POPJ P,
; To eat all extra spaces and tabs
J1SP: MOVNI C,3
ADDM C,(P) ;This backs up to the ILDB command
POPJ P,
; Action at end of a word signalled by a space or tab
J2TAB: MOVEI C,40
J2SP: MOVEI DSP,J1DSP
MOVSI H,JALL
J2SP1: TLNE F,TF1 ;Test for pass
JRST J2SP2 ;Second pass
AOS JSCNT ;Add to word break count
HRRZM G,JWCOL ;Char count to this word break
POPJ P,
; Second pass
J2SP2: TRNN F,NEG!REL ;Is this line to be justified?
JUSPAD: SKIPN T,JSINC ;8 times the needed number of extra spaces
POPJ P, ;Exit if no extra spaces are required
; To introduce extra spaces as required to justify
ADDB T,JSIZE
IDIV T,JSCNT ;Divide by available-location count
ADD T,JBUGR ;Current bugger factor to distribute extra spaces
LSH T,-3 ;Divide by 8
SUB T,JWPT ;JWPT counts additions to date
ADDM T,JWPT
JUMPE T,JUSPA2
JUSPA1:
LEG IDPB C,D ;Add an extra space
AOBJP G,JUSPA2 ;Should always be negative
SOJG T,JUSPA1
JUSPA2: POPJ P,
; Action on receipt of a sentence-terminating type punctuation mark
J2PUN: MOVEI DSP,J3DSP
MOVSI H,JALL
POPJ P,
; Action at end of sentence signalled by punctuation and space or tab
; or by punctuation then a closure then a space or tab
J3TAB: MOVEI C,40
J3SP: MOVEI DSP,J1DSP
TLNE F,TF1
JRST J3SP2 ;Its on the second pass
AOS JSCNT ;Add to word break count
HRRZM G,JWCOL ;Char count at this word break
TLNE F,TF3
JRST J3SP3 ;Woops! make this a par break
AOBJN G,J3SP1 ;Count for an extra space if possible
SUB G,[1,,1]
J3SP1: POPJ P,
J3SP2:
LEG IDPB C,D ;Introduce second space always
AOBJN G,J2SP2 ;(should always be OK)
POPJ P, ;Safety exit
J3SP3: TRO F,REL ;Signal end of par
AOS (P) ;Force exit from loop
POPJ P,
; Action on normal character if using JIDSP or J3DSP
J1CH: MOVEI DSP,J2DSP
MOVSI H,JUSF
POPJ P,
;Special dispatch tables used with JCTAB (Table address in DSP)
; and using the above routines
; After a space with JALL flag used
J1DSP: PUSHJ P,J2CR ;CR
PUSHJ P,J1SP ;TAB (eaten)
PUSHJ P,J1SP ;Space (eaten)
PUSHJ P,J1CH ;Punctuation (MOVEI DSP,J2DSP↔MOVSI H,JUSF)
PUSHJ P,J1CH ;Closure " "
PUSHJ P,J1CH ;Other character " "
; After a normal char. with JUSF flag used
J2DSP: PUSHJ P,J2CR ;CR
PUSHJ P,J2TAB ;TAB (MOVEI DSP,J1DSP↔MOVSI H,JALL)
PUSHJ P,J2SP ;Space " "
PUSHJ P,J2PUN ;Punctuation (MOVEI DSP,J3DSP↔MOVSI H,JALL)
JFCL ;(Never used)
JFCL ;(Never used)
; After sentence-terminating punctuation with JALL flag used
J3DSP: PUSHJ P,J2CR ;CR
PUSHJ P,J3TAB ;TAB (Replaced by space and handled as such)
PUSHJ P,J3SP ;Space (Introduces extra space and MOVEI DSP,J1DSP)
JFCL ;Punctuation
JFCL ;Closure
PUSHJ P,J1CH ;Other character (MOVEI DSP,J2DSP↔MOVSI H,JUSF)
; CENTER, INDENT, ALIGN, etc. routines and dispatch tables
; On finding a leading space
J4SP: AOJA T,J1SP ;Count then eat
; On finding the first non-space and non-tab
J4CH: CAILE Q,5
MOVEI Q,5
JRST @J4CHD(Q)
J4CHD: J4CH0 ;Go to appropiate code as determined by Q
J4CH1
J4CH2
J4CH3
J4CH4
J4CHX
; Set desired margin
J4CHX: MOVEI DSP,J5DSP
MOVSI H,JTBF!JCRF
PUSH P,C
PUSHJ P,JMSTRT ;Start line with appropiate margin
POP P,C
POPJ P,
; Get margin for INDENT
J4CH0: ADD T,INMAR
SKIPGE T
SETZ T,
JRST J4CHX
; Get margin for CENTER
J4CH1: SUB T,JWCOL ;Neg.of the number of text char. less initial spaces
ADD T,JSIZE
SKIPGE T
SETZ T,
LSH T,-1 ;Divide by 2
ADD T,LMAR
JRST J4CHX
; Get margin for ALIGN
J4CH2: MOVE T,AMAR
JRST J4CHX
; Get margin for RTARR
J4CH3: MOVE TT,INMAR
SKIPG TT
J4CH3A: MOVNS TT
J4CH3B: ADD T,TT
JUMPGE T,J4CHX
SETZ T,
JRST J4CHX
; Get margin for LFARR
J4CH4: MOVE TT,INMAR
JUMPG TT,J4CH3A
JRST J4CH3B
; On finding a CR before any other non-space characters
J4CR: MOVEI C,40
LEG IDPB C,D
AOS G
; On finding a CR after some text
J5CR: MOVEI DSP,J4DSP
MOVSI H,JALL
AOS (P) ;To skip the IDPB
AOS (P) ;To exit from loop
POPJ P,
; On finding an interior TAB
J5TAB: SKIPN JBUGR
JRST J1SP ;Eat it in this case
LEG IDPB C,D ;Write out first TAB when found
MOVSI T,1 ;TAB counts 1 in left of TXTCNT
ADDM T,TXTCNT(I)
HRRZ T,TXTCNT(I) ;Columns already accounted for
HRRZ TT,G ;Column count accumulating in G
ADD T,TT ;The actual column position
ANDI T,7 ;modulo 8
MOVEI TT,10
SUB TT,T
ADDM TT,TXTCNT(I)
MOVEI T,40
J5TAB2:
LEG IDPB T,D
SOJG TT,J5TAB2
LEG IDPB C,D ;Closing TAB
J5TAB3: ILDB C,A
CAIN C,40
JRST J5TAB3 ;Eat the spaces
CAIN C,11 ;Look for the closing TAB
JRST J1SP ;Eat it and go on
SOS (P)
SOS (P) ;Take a look at this character!
POPJ P, ;Should never get here, but just in case
; Initial dispatch table to eat spaces and tabs
J4DSP: PUSHJ P,J4CR ;CR (An all space line, maybe it is wanted)
PUSHJ P,J1SP ;TAB (eaten)
PUSHJ P,J4SP ;Space (counted then eaten)
PUSHJ P,J4CH ;Punctuation (MOVEI DSP,J5DSP↔MOVSI H,JTBF)
PUSHJ P,J4CH ;Closure " "
PUSHJ P,J4CH ;Other character " "
; In-text dispatch table to look for a TAB or a CR
J5DSP: PUSHJ P,J5CR ;CR
PUSHJ P,J5TAB ;TAB (special treatment depending on JBUGR setting)
JFCL
JFCL
JFCL
JFCL
;PARGET NEXTLI ADJARG JNEW JMORE JUFIX JBLANK JMSTRT
; Subroutine to get new par. indicator
PARGET: MOVE A,JCNT
CAIG A,1 ;Is this the last line?
JRST PARG2 ;Yes
HRRZ B,(B)
PARG0: HRRZ T,TXTCNT(B)
JUMPE T,PARG2
PARG1: MOVE A,B
ADD A,[440700,,LLDESC]
TRZ F,REL ;Means no new par.
MOVE T,A ;We will have to test new line indent
SETZ TT,
PARG1A: ILDB C,T ;Count leading spaces
CAIN C,40
AOJA TT,PARG1A
CAIN C,11
AOJA D,PARG1A
TLNE F,TF2 ;Was this a TABLE or TJ command?
JRST PARG4
SKIPN JSWTCH ;Is the N switch on?
JRST PARG3 ;Yes
CAMN TT,LMARO
POPJ P, ;Handles case where LMARO=PMARO
CAMN TT,PMARO ;Indent must match for all other switch settings
PARG2: TRO F,REL
POPJ P,
PARG3: CAILE TT,1 ;N switch case, any indent >1 indicates new par
TRO F,REL
POPJ P,
; TABLE or TJ case
PARG4: SKIPGE TABFLG
JRST PARG2 ;TABLE uses TPMARO always
SKIPN TJSWTC
JRST PARG3
CAMN TT,TLMARO
POPJ P, ;Handles case where TLMARO=TPMARO
CAMN TT,TPMARO ;Indent must match for all other switch settings
TRO F,REL
POPJ P,
; For second pass when input line is exhausted
NEXTLI: HLRZ T,TXTCNT(B)
MOVNI T,(T) ;and do 1's complement of T
ADDM T,@JCPTR(E) ;add this to # in CHARS or ATTSIZ.
SOS @JLPTR(E) ;Subtract 1 from # in LINES or ATTNUM.
MOVE A,B ;Old B value needed in A by FSGIVE
HRRZ B,(B) ;Get line forward pointer
MOVEM B,JPTR ;and put it in JPTR.
MOVSI T,JPTR ;with JPTR location in left half
HLLM T,(B) ;of pointer for line pointed to.
PUSHJ P,FSGIVE ;Give up storage space. (saves B)
MOVE A,B
ADD A,[440700,,LLDESC]
POPJ P,
; Limit neg A so as not to back too far, MOVARR and set A pos
ADJARG: MOVNS A
CAMGE A,ARRL ;Are we trying to go back too far?
JRST ADJAR1
MOVE A,ARRL ;Yes
SUBI A,1
ADJAR1: PUSH P,A
MOVNS A
PUSHJ P,MOVARR ;Now back up
MOVE T,WINLIN
MOVSI TT,WINBIT
ANDCAM TT,TXTFLG(T)
SETZM WINLIN
SETZM TOPWIN
ADJAR2: POP P,A ;Get positive count back
POPJ P,
; Get space for first new line
JNEW: PUSH P,Q
HRRZ Q,(B)
MOVEM Q,JRPT# ;Keep current next line address
CAMN B,PAGE
TRO F,UPDTXT ;This is the first line on the page
HLLZ Q,TXTFLG(B) ;Save flags
HRRZ I,FSEND
ADDI I,1
MOVEM I,JLPT
HLLZ TT,(B) ;Use the left half of old link for
LEG MOVEM TT,(I) ;left half of the new link word, zero right
HLRZ T,TT
HRRM I,(T) ;Fix earlier forward link to the new line
LEG HLLM Q,TXTFLG(I) ;Use old flags
TLNE Q,ARRBIT ;May need to reset ARRLIN
MOVEM I,ARRLIN
TLNE Q,WINBIT ;and also WINLIN
MOVEM I,WINLIN
CAMN B,ARRLIS
MOVEM I,ARRLIS ;Finally fix ARRLIS if necessary
POP P,Q
POPJ P,
; Get space for next output line
JMORE: HRRZ TT,FSEND ;So get space starting address
ADDI TT,1
HRRM TT,(I) ;Complete forward link in finished line
LEG HRLZM I,(TT) ;and back link new line
MOVEM TT,JLPT
MOVE I,JLPT
MOVEI TT,0
LEG HRLM TT,TXTFLG(I) ;This should always be safe
CAMN B,ARRLIS ;Does the data come from the original ARRLIN?
MOVEM I,ARRLIS ;Yes, so replace by I
POPJ P,
; Introduce CRLF and finish off the line
JUFIX: MOVEI C,15
LEG IDPB C,D ;The CR
MOVEI C,12
LEG IDPB C,D ;And a LF
TDZA C,C
LEG IDPB C,D ;And a null
TLNE D,760000
JRST .-2
MOVSI TT,2(G) ;2 for CRLF + char. count
ADDI TT,(G) ;but only char. count into right half
ADDM TT,TXTCNT(I) ;Record char counts
AOS @JLPTR(E) ;Add to line count (LINES or ATTNUM)
HLRZ T,TXTCNT(I)
ADDM T,@JCPTR(E) ;Add to char count (CHARS or ATTSIZ)
MOVE T,JLPT ;should be same as I
;Display text must be in ASCID
ADDI T,LLDESC ;Get address of first text word
MOVEI TT,1
IORM TT,(T) ;Convert to ASCID
CAIGE T,(D)
AOJA T,.-2
MOVEI TT,2(D)
MOVSI T,TXTCOD
FSFIX TT,T
POPJ P,
; To introduce a blank line
JBLANK:
LEG HRRZS TXTFLG(I) ;Zero flg portion
LEG SETZM TXTCNT(I) ;The 2,,0 will be added by JUFIX
AOS TT,TXTNUM
LEG HRRM TT,TXTSER(I)
SETZ G,
MOVE D,I
ADD D,[440700,,LLDESC]
MOVEI C,40
LEG IDPB C,D
PUSHJ P,JUFIX ;Finish off this line
POPJ P,
; To start new line with the proper margin
JMSTRT: AOS TT,TXTNUM
LEG HRRM TT,TXTSER(I) ;Assign I new serial number
MOVE D,I ;Set up output char pointer
ADD D,[440700,,LLDESC]
IDIVI T,10 ;See if TABs are to be used
LEG HRLZM T,TXTCNT(I) ;Start new TXTCNT (with credit for any TABs)
JUMPE T,J2PAS3 ;No TABs
PUSH P,Q ;Save Q
MOVEI C,11
J2PAS0:
LEG IDPB C,D
MOVEI C,40
MOVEI Q,10 ;Temporary use only
ADDM Q,TXTCNT(I) ;Count as displayed chars. only
J2PAS1:
LEG IDPB C,D
SOJG Q,J2PAS1
MOVEI C,11
J2PAS2:
LEG IDPB C,D
SOJG T,J2PAS0
POP P,Q ;Restore Q
J2PAS3: JUMPE TT,J2PAS5 ;No extra spaces in JMARG
HRR T,TT
HRL T,TT
ADDM T,TXTCNT(I) ;Count both as stored and as displayed
MOVEI C,40
J2PAS4:
LEG IDPB C,D
SOJG TT,J2PAS4
J2PAS5: POPJ P,
;JINIT JPREAD JMREAD JUDATA JUTYPO
; To determine E and get corrected JCNT and JPTR values
JINIT: TRNE F,ATTMOD ;Are we in ATTACH mode?
SKIPA E,[JATAB] ; Yes so put [JATAB] in E.
MOVEI E,JPTAB ; No so put [JPTAB] in E.
MOVE D,@JPT1(E) ;Put contents of @ATTBUF or @ARRLIN in D.
HRRZM D,JPTR# ;Location of first line to examine
MOVE A,@JLPTR(E) ;Number of lines
TRNE F,ATTMOD
JRST JINIT2
SUB A,ARRL
ADDI A,1
JINIT2: CAMGE A,JCNT
MOVEM A,JCNT ;Limit number of lines to the available ones
POPJ P,
JPREAD: MOVE T,EXTPNT ;To read JPARAM changing instructions.
MOVEM T,TYIPNT ;Set pointer.
HRLI C,(<MOVEI C,>)
MOVEM C,TYIINS
; Subroutine to read typed-in decimal numbers.
;Returns the number in A, the terminating character in C and
;a count of the number of digits in B.
JPARAM: SETZB A,B
TLZ F,TF1
JPAR0: PUSHJ P,TYI ;Get first character if any
POPJ P,
CAIN C," "
JRST JPAR0 ;Extra space allowed here
AOS (P) ;Skip return if something typed
CAIE C,"-"
JRST JPAR2
TLO F,TF1 ;Signal for a neg number
JPAR1: PUSHJ P,TYI ;Get next character
JRST JPAR3 ;End of typing
JPAR2: CAIG C,71
CAIGE C,60
JRST JPAR3 ;Non numeric character
IMULI A,12
ADDI A,-"0"(C)
AOJA B,JPAR1 ;B used to indicate some number (may be zero)
JPAR3: TLZE F,TF1
MOVNS A
POPJ P,
; To read switches then 4 margin values with possible additional old values
JMREAD: MOVSI Q,-4
SETOM JPMAR(Q)
SETOM JPMARO(Q)
AOBJN Q,.-2
SETOM JSWTC2
MOVSI Q,-4
PUSHJ P,JPREAD ;Get ready and read first parameter
POPJ P, ;Nothing typed
CAIG C,172
CAIGE C,141
SKIPA
SUBI C,40 ;Convert to upper case
CAIG C,132
CAIGE C,101
JRST JMREA2 ;No switch typed
MOVEI T,3 ;4 entries (one at 0) in SWTABL below
CAMN C,SWTABL(T)
SKIPA
SOJGE T,.-2
JUMPGE T,JMRES0
OUTSTR [ASCIZ/Only N, G, R or E recognized./]
JRST JMRES3
JMRES0: MOVEM T,JSWTC2 ;Save as new switch value
JMRES1: PUSHJ P,JPARAM ;Switch was read so now go ahead with margins
POPJ P, ;No margins typed
MOVSI Q,-4
CAIE C,40
CAIN C,"/"
JRST JMREA1 ;Ignore a space or a / here
CAIE C,","
CAIN C,"!"
JRST JMREA2
CAIN C,15
JRST JMREA2
JRST JMRES2
SWTABL: "N" ;Any indent >1 or blank line indicates new par.
"G" ;Get old indent from text
"R" ;Rejustify, previous output as input
"E" ;Exact indent as specified earlier is required
SWNOTE: OUTSTR [ASCIZ/Switch N (Normal, any indent >1) /]
OUTSTR [ASCIZ/Switch G (Get from text) /]
OUTSTR [ASCIZ/Switch R (Rejustify, previous output as input) /]
OUTSTR [ASCIZ/Switch E (Exact old input indent = /]
SWNOTT: OUTSTR [ASCIZ/Switch N (Normal, same as E for XTABLE) /]
OUTSTR [ASCIZ/Switch G (Get from text) /]
OUTSTR [ASCIZ/Switch R (Retabulate, previous output as input) /]
OUTSTR [ASCIZ/Switch E (Exact old input conditions /]
JMREA0: SKIPE B
MOVEM A,JPMARO(Q) ;Correct old value
JMREA1: PUSHJ P,JPARAM ;Read a parameter
POPJ P, ;Nothing typed
JMREA2: CAMN C,"|" ;Was a "|" separater used, meaning JPMARO (old)
JRST JMREA0 ;No
SKIPE B ;B=0 means no number before symbol
MOVEM A,JPMAR(Q)
CAIE C,40 ;A space or a comma may be used
CAIN C,"," ;Any other symbol terminates JGINIT
AOBJN Q,JMREA1
CAIN C,15
POPJ P,
JMRES2: CAIN C,";"
TLNN F,TF2
SKIPA
POPJ P,
OUTSTR [ASCIZ/Illegal syntax. /]
JMRES3: OUTSTR [ASCIZ/ Command aborted. /]
SETZM TYIPNT ;Ignore rest of command
POP P,C
JRST POPJ1
POPJ P,
JUDATA: MOVE T,JSWTCH
SKIPE JCNT ;Do not change if inquiry only
CAIE T,2
JRST JUS4
; G switch case
JUS3: PUSHJ P,JGMAR ;Get values from text
SETOM BNUMO
MOVSI Q,-3
MOVE T,GPMAR(Q)
MOVEM T,PMARO(Q)
AOBJN Q,.-2
JRST JUS5
JUS4: CAIE T,3
JRST JUS5 ;No change in PMARO for T switch
; R switch case
MOVSI Q,-4
MOVE T,PMAR(Q)
MOVEM T,PMARO(Q) ;Replace PMARO with PMAR values for R switch
AOBJN Q,.-2
JRST JUS5
; Test to see if any changes were made
JUS5: MOVSI Q,-3
SKIPL JPMAR(Q)
SETOM BNUM ;If BNUM not respecified when other changes
AOBJN Q,.-2
MOVSI Q,-4
JUS6: SKIPL T,JPMARO(Q)
MOVEM T,PMARO(Q)
SKIPL T,JPMAR(Q)
MOVEM T,PMAR(Q)
AOBJN Q,JUS6
POPJ P,
; To report on switches and margins
JUTYPO: MOVE T,JSWTCH
XCT SWNOTE(T) ;OUTSTR appropiate note
CAIE T,3
JRST JUTYP1
TYPDEC PMARO
OUTSTR [ASCIZ/) /]
JUTYP1: SKIPL BNUM
JRST JUTYP2
OUTSTR [ASCIZ/Margins are (P,L,R) /]
MOVSI Q,-3
JRST JUTYP3
JUTYP2: OUTSTR [ASCIZ/Margins are (P,L,R,B) /]
MOVSI Q,-4
SKIPA
OUTSTR [ASCIZ/,/]
JUTYP3: TYPDEC PMAR(Q)
AOBJN Q,.-2
OUTSTR [ASCIZ/. /]
POPJ P,
;TJIDSP TJ1DSP TJFILL TJUST TJDATA TJU1
; To terminate on a CR
TJ1CR: TLNE F,TF1 ;Is this the first pass?
JRST TJ1CR4 ;No
PUSHJ P,PARGET ;Is next line to be considered?
TRNN F,REL
JRST TJ1CR2 ;Yes
HRRZM G,JWCOL ;For the second pass
JRST JU3D
; Allow space to end of tab field
TJ1CR2: CAILE K,(G)
AOBJN G,TJ1CR2
SKIPG TT,TABTAB(Q) ;Are there any more fields?
JRST JU2 ;Let the main routine handle any remaining text
HRRZ K,TT
AOS Q
JRST TJ1CR2 ;Allow space for them also
TJ1CR3: AOS JSCNT ;Can count for a word break if necessary
HRRZM G,JWCOL ;Used to reset G on the second pass
JRST JU2
; Second pass
TJ1CR4: TRNE F,REL
JRST JU4A ;We are through
MOVEI C,40
MOVEI DSP,J1DSP
MOVSI H,JALL
JRST JU4
; To keep odd-even count on tabs and to eat them
TJ1TAB: MOVNS ODDEVN#
JRST J1SP ;MOVNI C,3↔ADDM C,(P)↔POPJ P,
; To exit from loop, on a non-space via TJ1DSP or on two spaces via TJ2DSP
TJ1CH: AOS (P)
AOS (P)
POPJ P,
TJ2TAB: ADD A,[70000,,0] ;Back up so odd-even count will work
CAIG A,0
SUB A,[430000,,1]
SOJA J,TJ2SP1 ;Correct for the AOJ which follows
; To test if there is more than 1 space (indicating the end of an entry)
TJ2SP: MOVE TT,A
ILDB C,TT ;Sneak look at the next character
CAIE C,40
CAIN C,11
JRST TJ2SP1
MOVEI C,40
POPJ P, ;Single spaces are allowed in tab fields
TJ2SP1: TLNN F,TF1 ;Which pass?
JRST TJ2SP2
MOVEI C,40 ;It could have been a tab
LEG IDPB C,D
LEG IDPB C,D
AOS (P) ;For the extra instruction in second-pass loop
TJ2SP2: AOBJN G,.+1 ;Count only 1 here and save second count until later
AOS J ;Also account for only 1 input char
AOS (P) ;to exit from loop
POPJ P,
; Dispatch table to eat to next tab field
TJ1DSP: JRST TJ1CR ;CR
PUSHJ P,TJ1TAB ;TAB (odd-even checked then eaten)
AOS J ;Space (counted to TABENO)
PUSHJ P,TJ1CH ;Punctuation (exit from loop)
PUSHJ P,TJ1CH ;Closure " " "
PUSHJ P,TJ1CH ;Other character " " "
; In-text dispatch table to look for a TAB or a CR
TJ2DSP: JRST TJ1CR ;CR
PUSHJ P,TJ2TAB ;TAB
PUSHJ P,TJ2SP ;SP
JFCL
JFCL
JFCL
; To reformat previously formatted files which have missing entries
TABLE: SETOM TABFLG# ;Marks this as a TABLE command
JRST TJUST0
; To reformat tables with no missing entries (may have appended information)
TJFILL: TROA F,NEG
TJUST: TRZ F,NEG
SETZM TABFLG ;Marks these as TJF or TJU commands
TJUST0: TLO F,TF2 ;Signal that this is a T type command
TLZ F,TF3 ;But not a JSPLIT
MOVEM A,JCNT ;Temporary value only
PUSHJ P,JMREAD ;Read typed margin values
SKIPGE T,JSWTC2 ;Was switch setting changed?
JRST TJUS2
SKIPL TABFLG
JRST TJUS1
JUMPG T,TJUS1
OUTSTR [ASCIZ/Only G, R and E switches work with XTABLE. Command aborted. /]
SETZM TYIPNT
POP P,C
JRST POPJ1
TJUS1: MOVEM T,TJSWTC
TJUS2: PUSHJ P,TJREAD
SKIPE JCNT ;Is this for real or for show?
JRST JUST2
PUSHJ P,TJDATA
PUSHJ P,TJTYPO
JRST POPJ1
TJDATA: MOVE T,TJSWTC
SKIPN JCNT
JRST TJU5
CAIE T,1
JRST TJUS4
; G switch case
TJUS3: PUSHJ P,JGMAR
SETOM TBNUMO
MOVSI Q,-3
MOVE T,GPMAR(Q)
MOVEM T,TPMARO(Q)
AOBJN Q,.-2
MOVSI Q,-TABCNT
MOVE T,TABTAB(Q) ;We want to change TABOLD and keep TABTAB
EXCH T,TABOLD(Q) ;but TJG1 resets TABTAB fron the text so
MOVEM T,TABTAB(Q) ;this double switch does it
AOBJN Q,.-3
PUSHJ P,TJG1 ;Get TABTAB values from text
MOVSI Q,-TABCNT
MOVE T,TABTAB(Q)
EXCH T,TABOLD(Q)
MOVEM T,TABTAB(Q)
AOBJN Q,.-3
JRST TJUS5
TJUS4: CAIE T,2
JRST TJUS5
; R switch case
MOVSI Q,-4
MOVE T,TPMAR(Q)
MOVEM T,TPMARO(Q)
AOBJN Q,.-2
HRLI T,TABTAB
HRRI T,TABOLD
BLT T,TABOLD+TABCNT-1
TJUS5: SKIPN TJRFLG ;Were some TABTAB changes made?
JRST TJUS5A
HRLI T,BUF2
HRRI T,TABTAB
BLT T,TABTAB+TABCNT-1
TJUS5A: MOVSI Q,-4
SKIPGE JPMARO(0)
SKIPL JPMAR(Q)
JRST TJUS6 ;At least 1 value changed
AOBJN Q,.-3
JRST TJUS7A
TJUS6: SETOM TBNUM ;Default value unless specified
MOVSI Q,-4
TJUS7: SKIPL T,JPMAR(Q)
MOVEM T,TPMAR(Q)
SKIPL T,JPMARO(Q)
MOVEM T,TPMARO(Q)
AOBJN Q,TJUS7
SETOM TJRFLG
TJUS7A: SKIPN TJRFLG
POPJ P,
TJUS8: MOVE TT,TPMAR ;Start TJADJ off right
PUSHJ P,TJADJ ;Adjust them
POPJ P,
; Special treatment if new par for TJ case
TJU1: SETZB Q,J
SKIPG TABOLD(Q) ;Are tab fields expected?
JRST JU2 ;No
TJU1A: MOVE K,TPMAR
MOVEM K,TABEND#
TLNE F,TF1 ;Which pass?
JRST TJU1B
TRZ F,REL ;Must be redetermined during first pass
SKIPGE TABFLG
TRO F,REL ;All lines are table lines for TABLE command
SETOM TF2FLG# ;Signalling first pass on a table line
TJU1B: SETOM ODDEVN ;To keep odd-even check on tabs
MOVEI TT,77777
SKIPGE TABFLG ;Is neg for TFJ commands
MOVE TT,TPMARO
MOVEM TT,TABENO#
JUMPE TT,TJU3B
TJU2: MOVEI DSP,TJ1DSP
MOVSI H,JALL
; Space eating loop (for both passes)
TJU3: ILDB C,A ;Eat spaces, odd-even check tabs, to next field
TJU3A: TLNE H,JCTAB(C)
XCT @JCTAB(C)
CAMGE J,TABENO
JRST TJU3
CAML J,TABENO ;Did we arrive at an entry too soon?
JRST TJU3B ;No
ADD A,[70000,,0] ;Yes, so back up
CAIG A,0
SUB A,[430000,,1]
JRST TJU3C
TJU3B: SKIPG ODDEVN ;Is there an unmatched tab?
JRST TJU3C ;No
MOVE T,A
ILDB C,T ;Sneak look at next char
CAIE C,11
JRST TJU3C ;Must be char for next field
ILDB C,A ;Eat it
MOVNS ODDEVN ;and account for it
TJU3C: TLNE F,TF1
JRST TJU6 ;Second pass
SKIPLE TT,TABOLD(Q)
JRST TJU4D ;Can continue
; Out of tab fields but is there any text on this line?
MOVE T,A
TJU4A: ILDB C,T
CAIE C,40
CAIN C,11
JRST TJU4A ;Eat spaces and tabs
CAIE C,15
CAIN C,12
JRST TJU4C ;End of this input line
TJU4B: CAILE K,(G)
AOBJN G,TJU4B
JRST JU2 ;Go read the text
TJU4C: PUSHJ P,PARGET
TRNN F,REL
JRST TJU4B ;There is text on the next line
HRRZM G,JWCOL ;Character count for second pass
SETZ JSINC ;To suppress any attempt to justify if no text
JRST JU3B ;Go to second pass
TJU4D: JUMPE Q,TJU4F ;Initial indent is handled differently
CAILE K,(G)
AOBJN G,.-1 ;Allow for the normal field length
TJU4F: SKIPGE TABFLG
HRRZM TT,TABENO ;New input field end
HRRZ K,TABTAB(Q) ;Establish the new output field termination
SUB K,TPMAR ;Remember that G right is to measure from TPMAR
JUMPG Q,TJU4E
TLNN F,TF1
HLLZS G ;First time fix so that G measures from TPMAR
TJU4E: AOS Q
MOVEI DSP,TJ2DSP
MOVSI H,JUSF
; First pass character count
TJU5: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C)
AOJA J,TJU5A ;Count input character and JUMP
AOBJN G,TJU2 ;Count second space here
MOVEI DSP,J1DSP
MOVSI H,JALL
JRST JU2 ;Let normal JUST or JFILL routine handle it
; Normal character portion of loop
TJU5A: AOBJN G,TJU5 ;Account for normal character
MOVEI DSP,J2DSP
MOVSI H,JUSF
JRST JU3A1
TJU6: SKIPLE TT,TABOLD(Q)
JRST TJU8
; There may be text to follow
MOVE T,A
TJU6A: ILDB C,T
CAIE C,40
CAIN C,11
JRST TJU6A ;Eat spaces and tabs
CAIE C,15
CAIN C,12
JRST TJU7C ;End of this input line
TJU7: MOVEI C,40 ;Pad out with spaces to end of this field
TJU7A: CAIG K,(G)
JRST TJU7B
LEG IDPB C,D
AOBJN G,TJU7A
TJU7B: MOVEI DSP,J1DSP ;Go read text
MOVSI H,JALL
JRST JU4
TJU7C: TRNN F,REL ;Are we to go to the next line?
JRST TJU7 ;Yes
JRST JU4A ;No, we are through
TJU8: JUMPE Q,TJU8B ;First indent handled by J2PASS
MOVEI C,40 ;Pad out with spaces to next field start
TJU8A: CAIG K,(G)
JRST TJU8B
LEG IDPB C,D
AOBJN G,TJU8A
TJU8B: SKIPGE TABFLG
HRRZM TT,TABENO ;New input field end
HRRZ K,TABTAB(Q)
SUB K,TPMAR ;Remember that G is measured from TPMAR
AOS Q
MOVEI DSP,TJ2DSP
MOVSI H,JUSF
; Second pass character transfer
TJU9: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C)
LEG IDPB C,D
AOJA J,TJU9A ;Count input character and JUMP
AOBJN G,TJU2 ;Count second space here
JRST JU4A
TJU9A: AOBJN G,TJU9 ;Count transfered character
JRST JU4A
;JSEPAR JJSEPA JFILL JUST
; To separate text into individual sentences, either filled or justified
JSEPAR: TROA F,NEG
JJSEPA: TRZ F,NEG
TLZ F,TF2
TLO F,TF3
JRST JUST0
; To left margin justify and, alternatively, to justify both margins
JFILL: TROA F,NEG ;For JFILL case
JUST: TRZ F,NEG ;For JUST case
TLZ F,TF2!TF3 ;Neither a TJ nor a JS command
JUST0: MOVEM A,JCNT ;Preliminary value only
PUSHJ P,JMREAD ;Read switch and typed margin values
CAIN C,15
JRST JUST2A
OUTSTR [ASCIZ/Too many characters! Command aborted./]
SETZM TYIPNT
JRST POPJ1
JUST2A: SKIPL T,JSWTC2
MOVEM T,JSWTCH
SKIPE JCNT ;Is this for real or for show?
JRST JUST2
PUSHJ P,JUDATA ;Accept typed values only
PUSHJ P,JUTYPO ;and report
JRST POPJ1
JUST2: PUSHJ P,ENDSET ;So new data will be at end of FS
TLO F,NOCHK ;Don't CORE DOWN untill through
MOVE A,ARRLIN
MOVEM A,ARRLIS# ;Save so we can reset arrow when done
MOVE A,TOPWIN
MOVEM A,TOPWIS#
MOVE A,JCNT
TRNN F,ARG!ATTMOD
JRST JU0A ;Start at beginning of page and do entire page
TRNN F,ARG
JRST JU0B ;Do entire ATTACH buffer
TRNN F,ATTMOD
JRST JU0 ;Still have to worry about a neg arg
JUMPG A,JU1
MOVNS A ;Neg argument if attached has no meaning
JRST JU1
JU0: JUMPG A,JU1
PUSHJ P,ADJARG ;Adjust A to start earlier and do thru init. ARRL
JRST JU1
JU0A: PUSHJ P,SETARR ;Start at beginning of page
MOVE T,WINLIN
MOVSI TT,WINBIT
ANDCAM TT,TXTFLG(T)
SETZM WINLIN
SETZM TOPWIN
JU0B: MOVEI A,-1
JU1: MOVEM A,JCNT ;Tentative line count
TRZ F,ARG ;This is used later to signal the end of data
PUSHJ P,JINIT ;Set E, get JPTR, and correct JCNT value
; Now we can interpret the switch and fix the margins
TLNE F,TF3
JRST JU1X ;A JSeparate command
TLNE F,TF2
PUSHJ P,TJDATA ;A TAble or TJ command
TLNN F,TF2
PUSHJ P,JUDATA ;JUST or JFILL
; Procede with justification
JU1X: MOVSI H,JALL ;Set to dispatch on all characters
MOVEI DSP,J1DSP ;Set dispatch for new output line
MOVE B,JPTR
TRZ F,REL ;Means not new par. on first pass
TLNE F,TF2 ;But is it a XTA OR XTJ command?
TRO F,REL ;Yes, first line considered new par.
SETZM JBUGR ;Bugger factor that staggers inserted spaces
JU1A: HRRZ C,TXTCNT(B) ;Is this line blank?
JUMPN C,JU1B ;No
HRRZ B,(B) ;Skip over it
MOVEM B,JPTR ;Initial blank lines are left but signal new par
SOSG JCNT ;One less line to process
JRST JU8
TRO F,REL ;Means new par. indent to start
JRST JU1A
JU1B: PUSHJ P,JNEW ;Get space for new lines and fix flags etc.
TRNN F,REL ;Alrready know that new par. indent is to be used
PUSHJ P,PARG0 ;Is this the start of a par?
JU1C: MOVE A,B
ADD A,[440700,,LLDESC]
JU1D: TLNE F,TF2 ;Was this a TJ command
JRST JU1E ;Yes
; Get normal margins
MOVE G,LMAR
TRNE F,REL ;No new par indent if 0
MOVE G,PMAR
MOVEM G,JMARG ;Save as current margin for second pass
SUB G,RMAR
JRST JU1F
; Get TJ margins
JU1E: MOVE G,TLMAR
TRNE F,REL ;No new par indent if 0
MOVE G,TPMAR
MOVEM G,JMARG ;Save as current margin for second pass
SUB G,TRMAR
JU1F: MOVNM G,JSIZE ;The expected size of new line less margin
SUBI G,1 ;Go 1 char. beyond on the first pass
HRLZS G
MOVEM A,ASAVE
SETZM JSCNT ;To count word separators
MOVE C,JCNT
MOVEM C,JCNTC
TLNE F,TF2
TRNN F,REL
SKIPA
JRST TJU1 ;Go to TJ routine if TJ command and new par
JU2: MOVEI DSP,J1DSP ;Always eat initial spaces
MOVSI H,JALL
TLZ F,TF1 ;Set for first pass
TRZ F,REL ;Must be redetermined during first pass
;First pass
; Determine accepted-char. count, # of word separators and par. conditions
JU3: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C) ;Caution, return may be .-2, ., .+1 or .+2
AOBJN G,JU3
JU3A1: SKIPN JSCNT ;Have we come to a word break?
JRST JU3 ;Impossible to break line so go on
JU3AA: SETZM JSINC ;Safety precaution only
; Verify par. conditions
TRNE F,REL ;Have we already determined par. conditions?
JRST JU3D ;Yes
LDB C,A ;GET last char. back
CAIN C,15 ;Was it a CR?
JRST JU3B ;YES, so no further testing needed
SKIPA
JU3A: ILDB C,A
CAIE C,40
CAIN C,11
JRST JU3A ;Eat all spaces and TABs
CAIE C,15 ;Now do we find a CR?
JRST JU3B ;No, so some text is left
PUSHJ P,PARGET ;Yes, so look at next line
JU3B: TRNN F,NEG!REL ;Is this a JFILL or a last line of par.
SOSG JSCNT ;Do not count final word ending
JRST JU3D ;Line must be left un-justified
; Prepare for justification
MOVE T,JSIZE
SUB T,JWCOL
LSH T,3 ;Multiply by 8
MOVEM T,JSINC
MOVN G,JSIZE
SETZM JSIZE ;Used in the JUSPAD routine for accumulated JSINC
SETZM JWPT ;Used in JUSPAD for accumulated insertions
SKIPA
JU3D: MOVN G,JWCOL ;Un-justified case
HRLZS G
; Prepare for the second pass
TLO F,TF1 ;Set for second pass
MOVE T,JMARG ;Get correct current margin value
PUSHJ P,JMSTRT ;Start new line with this margin
MOVE A,ASAVE
MOVE B,JPTR
MOVSI H,JALL
MOVEI DSP,J1DSP ;Always eat initial spaces
TLNE F,TF2
SKIPL TF2FLG ;Is set to -1 on first pass of table line
JRST JU4
SETZM TF2FLG
JRST TJU1 ;For second pass on table line
; Main character transfering loop
JU4: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C) ;Caution, return may be to .-2, ., or .+1
LEG IDPB C,D
AOBJN G,JU4
JU4A: PUSHJ P,JUFIX ;Fix up line just finished
TRNE F,ARG ;Is text exhausted?
JRST JU6D ;Yes
TLZ F,TF1 ;Get set for new first pass
TLNE F,TF3 ;Was it a JS command?
JRST JU5E ;Yes
TRNN F,REL ;Is it to be a new par?
JRST JU6 ;No
TLNE F,TF2 ;Is it a TJ command
MOVE Q,TBNUM ;Yes, so use proper value
TLNN F,TF2
MOVE Q,BNUM
JUMPLE Q,JU5B
JU5: SOS Q
JU5A: PUSHJ P,JMORE ;Get space
PUSHJ P,JBLANK ;Introduce blank line
JU5B: PUSHJ P,NEXTLI
SOSG JCNT
JRST JU7 ;No more text
HRRZ T,TXTCNT(B)
JUMPN T,JU5C
CAMN B,ARRLIS
MOVEM I,ARRLIS
JUMPG Q,JU5
JUMPL Q,JU5A
JRST JU5B
; Special treatment for XJS command
JU5E: TRZ F,REL ;Use LMAR indent always
MOVE T,A
JU5F: ILDB C,T ;Sneak look ahead
CAIE C,40
CAIN C,11
JRST JU5F
CAIE C,15
JRST JU6 ;Not a input line break
MOVE T,B
SETZ Q,
JU5G: HRRZ T,(T) ;Sneak look at next line
HRRZ TT,TXTCNT(T)
SKIPG TT ;No blank line
AOJA Q,JU5G
JU5C: JUMPLE Q,JU6
JU5D: PUSHJ P,JMORE
PUSHJ P,JBLANK
SOJG Q,JU5D
JU6: PUSHJ P,JMORE
JRST JU1D
JU6D: PUSHJ P,NEXTLI ;Give up final old line
;Complete the links to the following text
JU7: MOVE T,JLPT ;Now fix new right link
HRRM B,(T) ;A references next line
HRLM T,(B) ;And backward link to the new line
TRO F,WRITE!DSPALL
JU8: PUSHJ P,ENDFIX
TLZ F,NOCHK
TRNE F,ATTMOD
JRST JU9 ;Arrow was not moved in this case
MOVE B,PAGE
MOVEI A,1
JU8A: CAMN B,ARRLIS
JRST JU8B
HRRZ B,(B)
CAIE B,BOTSTR
AOJA A,JU8A
AOS A
JU8B: PUSHJ P,SETARR
MOVE A,TOPWIS
PUSHJ P,SETWIN
JU9: JRST JEXIT(E)
;IND INDENT CENTER ALIGN LFARR RTARR
; Common routine used by CENTER, INDENT etc. with proper dispatch value in DSP
IND: SETZM JBUGR ;Normal case where TABs are replaced by spaces
CAIE C,"T" ;Was the TAB flag typed?
CAIN C,"t"
SETOM JBUGR ;Signals retention of internal TABs
PUSHJ P,ENDSET ;So new data will be at end of FS
TLO F,NOCHK ;Don't CORE DOWN untill through
MOVE A,ARRLIN
MOVEM A,ARRLIS# ;Save so we can reset arrow when done
MOVE A,TOPWIN
MOVEM A,TOPWIS#
POP P,A ;The initial argument saved by CENTER or INDENT
TRNE F,ATTMOD
JRST IND2
JUMPGE A,IND3
PUSHJ P,ADJARG ;Adjust argument and back up if neg
JRST IND3
IND2: SKIPGE A
MOVNS A ;NEG value has no meaning if in ATTACH
TRNN F,ARG
MOVEI A,-1 ;Do entire ATTACH buffer if no argument
IND3: MOVEM A,JCNT ;Tentative count of lines to process
PUSHJ P,JINIT ;Set E, get JPTR and correct JCNT
MOVE B,JPTR
IND4: HRRZ C,TXTCNT(B) ;Is this a blank line?
JUMPN C,IND4A
HRRZ B,(B)
SOSG JCNT
JRST JU8 ;No non-blank lines (finish off as in JUST)
JRST IND4 ;Delay starting until first non-blank line
IND4A: PUSHJ P,JNEW ;Get space for first line
IND5: SETZ T, ;Used to count leading spaces
MOVEM C,JWCOL ;Save character count for use in CENTER
MOVE A,B
ADD A,[440700,,LLDESC]
MOVSI G,-77777
MOVEI DSP,J4DSP
MOVSI H,JALL
SETZ T,
; Main loop
IND6: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C)
LEG IDPB C,D
AOBJN G,IND6
PUSHJ P,JUFIX ;Add CRLF and finish off this line
IND7: PUSHJ P,NEXTLI
SOSG JCNT
JRST JU7 ;No more lines (finish as for JUST)
PUSHJ P,JMORE ;Get space for nest line
HRRZ C,TXTCNT(B) ;Is the next line blank?
JUMPG C,IND5
PUSHJ P,JBLANK ;Put in the blank line
JRST IND7
INDENT: PUSH P,A ;Will be restored in IND
PUSHJ P,JPREAD
SKIPA ;Use default value
MOVEM A,INMAR
MOVEI Q,0 ;Signal to J4CH to use INDENT margin code
JRST IND
CENTER: PUSH P,A
MOVSI Q,-4
SETOM JPMAR(Q)
AOBJN Q,.-1
PUSHJ P,JMREAD ;Read typed margin values
MOVSI Q,-4
CENT0: SKIPL T,JPMAR(Q)
MOVEM T,PMAR(Q)
AOBJN Q,CENT0
MOVE T,RMAR
SUB T,LMAR
MOVEM T,JSIZE ;Use for centering
MOVEI Q,1 ;Signal to J4CR to use CENTER margin code
JRST IND ;use same routine as INDENT
; ALIGN command aligns all specified lines at a fixed left margin
ALINE:
ALIGN: PUSH P,A
PUSHJ P,JPREAD
JRST ALIGN2
SKIPGE A
SETZ A,
MOVEM A,AMAR
ALIGN2: MOVEI Q,2 ;Signal to J4CH to use code for ALIGN
JRST IND
; Moves the specified lines right by the (absolute) INMAR value
RTARR: PUSH P,A ;Will be restored in IND
MOVEI Q,3
JRST IND
; Moves the specified lines left by the (absolute) INMAR value
LFARR: PUSH P,A ;Will be restored in IND
MOVEI Q,4
JRST IND
JLEFT: OUTSTR [ASCIZ/Not defined/]
popj p,
;JGINIT JGB JGIND JGMAR JGET
; Subroutine called by JGET and TJGET
;to clear PAR table and to read and store typed-in MAR values.
JGINIT: TRNN F,ARG
HRRZI A,-1 ;Use rest of page (or buffer) if no argument
MOVMM A,JCNT
JUMPE A,JGIN1 ;No text referencing
MOVSI Q,-4
SKIPN JCNT
POPJ P, ;Leave old values if JCNT=0 and no typed value
SETOM JPMAR(Q)
AOBJN Q,.-1
PUSHJ P,JINIT ;Set E and get proper JPTR and JCNT values
MOVN G,JCNT
HRLZS G
MOVEM G,GSAVE# ;May be needed again later
JGIN1: POPJ P,
; Subroutine called by JGMAR
;Will locate the first non-blank line after 1 or more blank lines and
;return the number of blank lines in B (B set to 0 before entry).
;Pointer to the first line of text in D and the specification of the number
;of lines of text (as a negative number) in the left of G.
JGB0: HRRZ D,(D)
JGB: HRRZ C,TXTCNT(D)
JUMPN C,JGB1
AOJA B,JGB2 ;Count blank lines for JBNUM
JGB1: CAMLE C,Q
MOVE Q,C ;Put largest in Q for JRMAR
JUMPE B,JGB2
MOVEM B,GBNUM ;Save it here always
MOVEM G,GSAVE ;May be needed twice
MOVEM D,DSAVE# ;Save new starting place in text
JRST JGB1B
JGB1A: HRRZ D,(D) ;Go to end for Q determination
HRRZ C,TXTCNT(D)
CAMLE C,Q
MOVE Q,C
JGB1B: AOBJN G,JGB1B ;Are we at the end?
MOVE G,GSAVE ;Reset for first line after blanks
MOVE D,DSAVE
POPJ P, ;Text found after a blank line
JGB2: AOBJN G,JGB0 ;Still looking
MOVE D,JPTR ;No text found after blank line, so reset
MOVE G,GSAVE
SETZ B, ;Use B now to count lines having same indent
MOVEM B,GBNUM ;This says no blank lines in text
JGB2A: PUSHJ P,JGIND ;Get first line indent
HRRZ TT,T ;Save it
JGB3: AOBJP G,JGB4
HRRZ D,(D) ;Try the next line
PUSHJ P,JGIND
CAIN TT,(T)
AOJA B,JGB3 ;Another line with the same indent
JUMPE B,JGB4 ;More than 1 line with same indent?
MOVEM G,GSAVE
MOVEM D,DSAVE
POPJ P,
JGB4: MOVE G,GSAVE ;Go back to first line if B still zero
MOVE D,JPTR
POPJ P,
;To get indentation
JGIND: HRRZ T,TXTCNT(D)
MOVNS T
HRLZS T
MOVE A,D
ADD A,[440700,,LLDESC]
JGIND1: ILDB C,A
CAIN C,11 ;Is it a TAB?
JRST JGIND1 ;Ignore it
CAIN C," " ;Is it a space?
AOBJN T,JGIND1 ;Count it
POPJ P,
; Subroutine called by JGET and TJGET
;To determine margins from specified text
JGMAR: MOVN G,JCNT
HRLZS G
MOVEM G,GSAVE ;May be needed twice
SETZB B,Q ;B counts blank lines, Q gets JRMAR
SETOM GBNUM
MOVE D,JPTR ;Pointer to the first line of text
PUSHJ P,JGB ;Find paragraph start
PUSHJ P,JGIND ;Get its indentation
MOVEM T,INDCNT# ;May be needed for TJGET case
MOVEM A,ASAVE# ;and also pointer to first non-blank character
HRRZM T,GPMAR
AOBJN G,JGM0 ;Trouble, not enough lines
SETZM GBNUM ;Maybe he wants 1 paragraph
JRST JGMA
JGM0: HRRZ D,(D)
PUSHJ P,JGIND ;Get indentation of the next line
JGMA: HRRZM T,GLMAR
MOVEM Q,GRMAR ;No, so save this value
POPJ P,
;Get typed-in margins from the specified text.
JGET: JUMPE A,JGET2
PUSHJ P,JGINIT
PUSHJ P,JGMAR ;Get margins by examining the text
SETOM BNUM ;Default value used always with JGET
MOVSI Q,-3
MOVE T,GPMAR(Q)
MOVEM T,PMAR(Q)
AOBJN Q,.-2
JGET2: OUTSTR [ASCIZ/Margins (P,L,R) from text are /]
MOVSI Q,-3
SKIPA
OUTSTR [ASCIZ/,/]
JGET5: TYPDEC PMAR(Q)
AOBJN Q,.-2
OUTSTR [ASCIZ/./]
POPJ P,
;TJREAD TJADJ TJGET TJG1 TJTYPO
; To read typed tab values
TJREAD: SETZM TJRFLG
CAIE C,";"
CAIN C,"!"
SKIPA
POPJ P, ;No typed TAB values
SETOM TJRFLG#
HRLI T,TABTAB
HRRI T,BUF2
BLT T,BUF2+TABCNT-1 ;Use BUF2 temporarily
MOVSI Q,-TABCNT
HLLZS BUF2(Q) ;Zero indent values only
AOBJN Q,.-1
MOVSI Q,-TABCNT
CAIN C,"!"
JRST TJR4 ;Next number is to be an indent not a field size
TJR2: PUSHJ P,JPARAM
POPJ P, ;No more data
CAIE C,"@" ;Is this a multiple define
JRST TJR5
MOVE H,A ;Yes, so save repetition number in H
PUSHJ P,JPARAM ;and get field size
SETZ A, ;No-value-typed return
SKIPLE A ;A zero or missing value means leave unchanged
TJR3: HRLZM A,BUF2(Q)
AOBJP Q,TJR7 ;No more space so ignore the rest
SOJG H,TJR3
JRST TJR6 ;See if there are any more
TJR4: PUSHJ P,JPARAM ;Get indent value
SKIPA ;Syntax error
JUMPG A,TJR4A ;An indent can not be zero
OUTSTR [ASCIZ/IMPROPER SYNTAX, a non-zero number must follow a "!" symbol/]
JRST TJR9
TJR4A: HRRZM A,BUF2(Q)
AOBJP Q,TJR7
JRST TJR6
TJR5: JUMPG A,TJR5A ;Was a number typed?
CAIE C,"Z"
CAIN C,"z"
JRST TJR8
SKIPA
TJR5A: HRLZM A,BUF2(Q) ;Save it as a field length
AOBJP Q,TJR7
TJR6: CAIN C,","
JRST TJR2
CAIN C,"!"
JRST TJR4
CAIE C,"Z"
CAIN C,"z"
JRST TJR8
CAIN C,15
POPJ P,
OUTSTR [ASCIZ/Improper syntax. Command aborted. /]
TJR9: SETZM TYIPNT
POP P,C
JRST POPJ1
TJR7: OUTSTR [ASCIZ/ Field table is full, will ignore rest. /]
TJR8: SETOM BUF2(Q)
SETZM TYIPNT
POPJ P,
; To adjust right half fields of TABTAB to reflect all typed changes
TJADJ: MOVSI Q,-TABCNT ;Must be entered with margin value in TT
HLLZS TABTAB(Q)
AOBJN Q,.-1
MOVSI Q,-TABCNT
TJADJ1: SKIPG TABTAB(Q)
JRST TJADJ4
HLRZ T,TABTAB(Q)
JUMPG T,TJADJ3 ;A field length was specified
HRRZ T,TABTAB(Q) ;An indent was specified
SUB T,TT
CAIL T,MINTXT
JRST TJADJ2
OUTSTR [ASCIZ/ TAB field #/]
HRRZ C,Q
TYPDEC C
OUTSTR [ASCIZ/ set at min. length of /]
MOVEI T,MINTXT
TYPDEC T
OUTSTR [ASCIZ/. /]
TJADJ2: HRLM T,TABTAB(Q)
TJADJ3: ADD TT,T
HRRM TT,TABTAB(Q) ;May have been corrected
AOBJN Q,TJADJ1
TJADJ4: TRNN Q,777
POPJ P, ;No fields specified
CAMLE TT,TRMAR ;Was TRMAR large enough?
MOVEM TT,TRMAR
POPJ P,
;Get margins and TAB settings from text
TGET:
TJGET: SETOM TABTAB
HRLI T,TABTAB
HRRI T,TABTAB+1
BLT T,TABTAB+TABCNT-1
PUSHJ P,JGINIT ;Initialize
PUSHJ P,JGMAR ;Get margins by examining the text
SETOM TBNUM
SKIPG B
MOVEM B,TBNUM
MOVSI Q,-3
MOVE T,GPMAR(Q)
MOVEM T,TPMAR(Q)
AOBJN Q,.-2
PUSHJ P,TJG1 ;Get tabular values
PUSHJ P,TJTYPO ;Report
JRST POPJ1
; To get table data from text
TJG1: MOVSI Q,-TABCNT
MOVE A,ASAVE ;Get back to the first non-space char in 1st line
MOVE G,INDCNT ;Get character counter for first non-space
SETZM TABMAX#
TJG2: SETZ T,
TJG3: SETZ H,
TJG4: AOS T ;We start on the first char
ILDB C,A
CAIE C," "
CAIN C,11
JRST TJG8
CAIE C,15 ;Must exit on CR
AOBJN G,TJG4
TRNN Q,777 ;Were any fields found?
JRST TJTYPO ;No, so report on margins
CAMLE T,TABMAX
JRST TJG15 ;Not a normal tab field
MOVE T,TABMAX ;Make last field as long as the max.
HRLZM T,TABTAB(Q)
JRST TJG15
;To count spaces or TABS to check field termination
TJG5: AOS H
TJG6: AOS T
TJG7: ILDB C,A ;A space or TAB found, is there another one?
TJG8: CAIE C," " ;Is it a space?
JRST TJG9
AOBJN G,TJG5
JRST TJG15
TJG9: CAIN C,11 ;or a TAB?
AOJA H,TJG7 ;TABs do not count in G or T, but add to H
CAIL H,TJSCNT ;Were there JSCNT or more spaces?
JRST TJG13 ;Yes, so at end of this TAB field
AOBJN G,TJG3 ;Single spaces allowed within fields
JRST TJG15
TJG10: OUTSTR [ASCIZ/ Only /]
MOVEI A,TABCNT
TYPDEC A
OUTSTR [ASCIZ/ TABS allowed. /]
JRST TJG15
TJG13: CAMLE T,TABMAX
MOVEM T,TABMAX
HRLZM T,TABTAB(Q) ;Save field length
AOBJP Q,TJG10
AOBJN G,TJG2
TJG15: MOVE TT,TPMAR
PUSHJ P,TJADJ ;Adjust all tab values to reflect corrections
TJG18: MOVEI Q,TABCNT
SKIPG TABTAB(Q)
SOJG Q,.-1
HRRZ TT,TABTAB(Q)
CAMLE TT,TRMAR
MOVEM TT,TRMAR ;Correct to account for extended last tab
POPJ P,
; To report on TAB and TJ switch, margins and tabular settings
TJTYPO: OUTSTR [ASCIZ/"T" /]
MOVE T,TJSWTC
SKIPGE TABFLG
JRST [XCT SWNOTT(T)↔JRST TJTYP1] ;Different note for XTABLE
XCT SWNOTE(T) ;OUTSTR appropiate note
CAIE T,2
JRST TJTYP1
TYPDEC TPMARO
OUTSTR [ASCIZ/) /]
TJTYP1: SKIPL TBNUM
JRST TJG18A
OUTSTR [ASCIZ/Margins (P,L,R) are /]
MOVSI Q,-3
JRST TJG19A
TJG18A: OUTSTR [ASCIZ/Margins (P,L,R,B) are /]
MOVSI Q,-4 ;Report values
SKIPA
TJG19: OUTSTR [ASCIZ /,/]
TJG19A: TYPDEC TPMAR(Q)
AOBJN Q,TJG19
SKIPG TABTAB ;Are there any TABS?
JRST TJG23
MOVSI Q,-TABCNT
SKIPLE TABTAB(Q)
AOBJN Q,.-1
ANDI Q,777
OUTSTR [ASCIZ/;
/]
TYPDEC Q
OUTSTR [ASCIZ/ fields /]
MOVSI Q,-TABCNT
SKIPA
TJG20: OUTSTR [ASCIZ/,/]
SETZ H,
HLRZ T,TABTAB(Q)
TJG20A: HLRZ TT,TABTAB+1(Q)
CAME T,TT
JRST TJG20B
AOS H
AOBJN Q,TJG20A
TJG20B: JUMPE H,TJG20C
AOS H ;The first one was not counted
TYPDEC H ;Count of similar fields
OUTSTR [ASCIZ/@/]
TJG20C: TYPDEC T
SKIPLE TABTAB+1(Q)
AOBJN Q,TJG20
TJG21: OUTSTR [ASCIZ/ indented /]
MOVE T,TPMAR
TYPDEC T
MOVSI Q,-TABCNT
TJG22: SKIPLE TABTAB+1(Q)
OUTSTR [ASCIZ/,/]
HRRZ T,TABTAB(Q)
SKIPG TABTAB+1(Q)
JRST TJG24
TYPDEC T
AOBJN Q,TJG22
TJG24: CAML T,TRMAR
JRST TJG25
OUTSTR [ASCIZ/, text /]
TYPDEC T
TJG25: OUTSTR [ASCIZ/. /]
POPJ P,
TJG23: OUTSTR [ASCIZ/ No tabulation found./]
POPJ P,
;BREAK JOIN
;To break a specified number of lines into fragments ≤BREAKV in length
BREAK: TLZ F,JOINF ;Not to be a JOIN
MOVEM A,JCNT ;Number of lines, default value is 1
MOVE T,EXTPNT ;To read break length if specified
MOVEM T,TYIPNT ;Set pointer.
HRLI C,(<MOVEI C,>)
MOVEM C,TYIINS
SETZB A,C
BREAK0: PUSHJ P,TYI ;Get first character if any.
JRST BREAK4 ;We are to use default value
CAIN C," "
JRST BREAK0 ;Ignore an extra space in here.
BREAK1: CAIG C,71
CAIGE C,60
JRST BREAK3
IMULI A,12
ADDI A,-"0"(C)
PUSHJ P,TYI
JRST BREAK2
JRST BREAK1
BREAK2: JUMPG A,BRK2A
SORRY BREAK length of 0 not allowed.
JRST POPJ1
BRK2A: CAILE A,377770
MOVEI A,377770 ;This should be large enough!
MOVEM A,BREAKV ;Break value is always sticky
BREAK4: SKIPLE JCNT ;Non-positive arg means just tell default value
JRST JOIN0 ;BREAK something now
OUTSTR [ASCIZ /Default BREAK length is now /]
SETZM TYOPNT
TYPDEC BREAKV
OUTSTR [ASCIZ /. /]
JRST POPJ1 ;Abort on 0 or neg argument
BREAK3: SORRY Only digits permitted in following arg.
SETZM TYIPNT
JRST POPJ1
;To join a specified number of lines into 1 continuous line of arbitrary max length
JOIN: TRNN F,ARG
MOVEI A,2
JUMPG A,JOIN0A
SORRY JOIN argument must be positive.
JRST POPJ1 ;Abort on 0 or neg argument
JOINPM: SORRY Cannot JOIN or BREAK a non-text line.
JRST POPJ1
JOIN0A: MOVEM A,JCNT
TLO F,JOINF ;Set JOIN flag
JOIN0: TRNE F,ATTMOD ;Don't care about arrow line if doing attach buffer
JRST JOIN0B
TLNE F,PMLIN!OFFEND
JRST JOINPM ;Current line is pagemark
JOIN0B: PUSHJ P,ENDSET ;To guarentee that new line will be at the end of FS
TLO F,NOCHK ;Don't CORE DOWN untill through
TRNE F,ATTMOD ;Are we in ATTACH mode?
SKIPA E,[JATAB] ; Yes so put [JATAB] in E.
MOVEI E,JPTAB ; No so put [JPTAB] in E.
HRRZ A,@JPT1(E) ;Put right of @ATTBUF or @ARRLIN in A
MOVEM A,JPTR ;Address of link word for first line of text
HLLZ Q,TXTFLG(A) ;Save flags
;Link up start of new area in place of the old
HRRZ H,FSEND
ADDI H,1
TLNE F,JOINF
JRST JOINB ;Join bypass
JOINA: HRRZ T,TXTCNT(A) ;Get size of the line
CAMLE T,BREAKV ;Is line short enough already?
JRST JOINB ;No
SETZ Q, ;Yes, next line cannot be ARRL
HRRZ A,(A) ;Go to it
MOVEM A,JPTR ;Reset for later FSGIVE
CAME A,JETST(E) ;Are we at the end?
SKIPGE TXTFLG(A)
JRST JOINA1
SOSLE JCNT ;or has count run out?
JRST JOINA ;Maybe better luck next time
JOINA1: PUSHJ P,ENDFIX
TLZ F,NOCHK
OUTSTR [ASCIZ /No lines broken. /]
AOS (P)
POPJ P, ;Nothing to do
JOINB:
LEG HLLM Q,TXTFLG(H) ;Use old flags
TLNE Q,ARRBIT ;May need to reset ARRLIN
MOVEM H,ARRLIN
TLNE Q,WINBIT ;and also WINLIN
MOVEM H,WINLIN
SETZ Q,
MOVEM H,JLPT
HLLZ TT,(A) ;Use the left half of old link for
LEG MOVEM TT,(H) ;left half of the new link word, zero right
HLRZ T,TT
HRRM H,(T) ;Fix earlier forward link to the new line
AOS TT,TXTNUM
LEG HRRM TT,TXTSER(H) ;Assign H new serial number
ADD H,[440700,,LLDESC] ;Pointer for depositing text
CAIN T,PAGE
TRO F,UPDTXT ;This is the first line on the page
MOVN B,BREAKV ;Set for BREAK
TLNE F,JOINF
MOVEI B,400000 ;Set very large for JOIN
HRLZS B
SETZ G,
JOIN1A: SETZ I, ;To accumulate counts for null line detection
JOIN1: HRRZ T,TXTCNT(A) ;Is this a null line?
JUMPE T,JOIN4 ;Null line bypass
MOVE D,A
ADD D,[440700,,LLDESC] ;Pointer to read text
ADD I,T
JRST JOIN3
;Transfer text, counting chars and fixing up TABs
JOIN2:
LEG IDPB C,H
JOIN3: ILDB C,D
CAIN C,11 ;Is it a TAB?
JRST JOIN5 ;Yes
CAIN C,15
JRST JOIN4
AOBJN B,JOIN2
JOIN2A:
LEG IDPB C,H ;Not a CR so save it
MOVE TT,D
ILDB C,TT ;Sneak a look at next char
CAIE C,15 ;Is it a CR?
JRST JOIN6A ;No, so there is something to break off
TLO B,400000 ;Nothing willl be left so make B neg
JOIN4: AOS Q
;Test for end of text and fix up for next line
HRRZ A,(A) ;Look at next line
SKIPL TXTFLG(A)
CAMN A,JETST(E) ;Are we at BOTSTR or ATTBUF?
SETZM JCNT ;This is needed later
SOSLE JCNT ;Have we joined the specified number of lines?
TLNN F,JOINF ;Or is it a CR for a BREAK?
JRST JOIN6 ;Yes
SOS @JLPTR(E) ;1 line removed from LINES or ATTNUM
SOS @JCPTR(E) ;But correct CHARS or ATTSIZ now
SOS @JCPTR(E) ;for both CR and LF that will be deleted
JRST JOIN1
;Routine for fixing TABs
JOIN5: ILDB C,D ;Yes
CAIN C,40
JRST .-2 ;Eat original spaces
; CAIE C,11 ;Spaces should terminate in a TAB
; OUTSTR [ASCIZ /TAB trouble, inspect text carefully for char omission. /]
;Now put in correct number of spaces for deposited position in line
LEG IDPB C,H ;Deposit as initial TAB
HRROI TT,-10
IORI TT,(B)
HRLS TT ;So that B-left is properly updated
SUB B,TT
ADDI G,(TT)
MOVEI T,40
JRST .+11(TT)
REPEAT 10,<LEG IDPB T,H>
AOS G
JUMPL B,JOIN2 ;Jump if have room for more in this line
JRST JOIN2A
;JOIN6 finishes off the line
JOIN6: JUMPG I,JOIN6A ;Not a null line
MOVEI C,40
LEG IDPB C,H ;At least 1 char is required
MOVSI B,-1 ;Mark input line as used up, output line as empty
JOIN6A: MOVEI C,15
LEG IDPB C,H ;The CR
MOVEI C,12
LEG IDPB C,H ;And a LF
TDZA C,C
LEG IDPB C,H ;And a null
TLNE H,760000
JRST .-2
MOVE T,JLPT
ADDI G,2(B)
HRLZS G
ADDI G,(B)
LEG MOVEM G,TXTCNT(T) ;Record char counts
;Text must be in ASCID
ADDI T,LLDESC ;Get address of first text word
MOVEI TT,1
IORM TT,(T) ;Convert text words to ASCID
CAIGE T,(H)
AOJA T,.-2
MOVEI TT,2(H)
MOVSI T,TXTCOD
FSFIX TT,T
SKIPG JCNT ;Have we exhausted the input?
JRST JOIN7 ;Yes, (will always be so if here on a JOIN)
BREAK6: MOVE T,JLPT ;We will need more space
HRRZ H,FSEND
ADDI H,1 ;Get its start
HRRM H,(T) ;and link it to last piece
LEG HRLM T,(H)
MOVEM H,JLPT
MOVE T,B ;Save for test
MOVN B,BREAKV ;Reset counters
TRNN F,ARG!REL ;If no argument given to BREAK,
MOVEI B,400000 ; then make sure we don't break the line again
HRLZS B
SETZ G,
LEG HRLM G,TXTFLG(H) ;Broken-off piece or next line cannot be ARRL
AOS TT,TXTNUM
LEG HRRM TT,TXTSER(H)
ADD H,[440700,,LLDESC]
JUMPL T,JOIN1A ;There was at a CR in original text so reset
AOS @JLPTR(E) ;An extra line will be added
AOS @JCPTR(E) ;And 2 extra chars
AOS @JCPTR(E)
JRST JOIN3
;And complete the links to the following text
JOIN7: MOVE T,JLPT ;Now fix new right link
HRRM A,(T) ;A references next line
HRLM T,(A) ;And backward link to the new line
PUSHJ P,ENDFIX
;It should be safe to FSGIVE now, count is in Q
MOVE A,JPTR ;Get back address of first old line
JUMPE Q,.+4
PUSHJ P,FSGIVE ;And give up its space
HRRZ A,(A)
SOJG Q,.-2 ;Do this for all the old lines
TRO F,WRITE!DSPALL
TLZ F,NOCHK
TLNN F,JOINF ;No message on a break
JRST JEXIT(E)
MOVE T,JLPT ;Restore T value
HRRZ B,TXTCNT(T) ;and check final length of joined line
SETZM TYOPNT
OUTSTR [ASCIZ /Line now has /]
TYPDEC B
OUTSTR [ASCIZ / chars. /]
AOS (P)
JRST JEXIT(E)
;SHIFTY
;This routine tests all lines of text that are in the ATTACH buffer for
;the presence of a space or a TAB in the first chararacter as a prelude
;to the execution of left shift.
SHIFTY: HRRZ D,[ATTBUF] ;Needed for completion test.
MOVE T,(D) ;Get starting location
SHFTY1: MOVE A,[350700,,3(T)] ;Pointer to the first word of text
LDB C,A ;and the first character
CAIE C,40 ;Is it a space?
CAIN C,11 ;or maybe a TAB?
JRST .+2 ;Good!
JRST SHFTY2 ;Too bad, give message and return
CAIN D,(T) ;Are we through?
AOJA P,SHFTY3 ;Yes, so use second return
MOVE T,(T) ;Go to next line of text
JRST SHFTY1 ;and go on
SHFTY2: SORRY One line (at least) is as far as it can go.
SHFTY3: POPJ P,